package com.qqs.distributed.annotation;

import com.qqs.distributed.advice.CacheAttribute;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.AnnotatedElement;
import java.util.concurrent.TimeUnit;

public class AnnotationCacheAnnotationParsers implements CacheAnnotationParser {
    private DistributedCacheProperties cacheProperties;

    public AnnotationCacheAnnotationParsers() {
    }

    @Override
    public boolean isCandidateClass(Class<?> targetClass) {
        return AnnotationUtils.isCandidateClass(targetClass, Cache.class);
    }

    @Override
    public CacheAttribute parseCacheAnnotationParser(AnnotatedElement element) {
        AnnotationAttributes annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
                element, Cache.class, false, false);
        if (annotationAttributes != null) {
            return parseCacheAnnotation(annotationAttributes);
        }
        return null;
    }

    public CacheAttribute parseCacheAnnotation(AnnotationAttributes annotationAttributes) {
        CacheAttribute cacheAttribute = new CacheAttribute();
        CacheType cacheType = annotationAttributes.getEnum("cacheType");
        cacheAttribute.setCacheType(cacheType);
        LockType lockType = annotationAttributes.getEnum("lockType");
        cacheAttribute.setLockType(lockType);
        String cacheKeyExpr = annotationAttributes.getString("cacheKeyExpr");
        cacheAttribute.setCacheKeyExpr(cacheKeyExpr);
        String bloom = annotationAttributes.getString("bloom");
        cacheAttribute.setBloom(bloom);
        long ttl = annotationAttributes.getNumber("ttl").longValue();
        cacheAttribute.setTtl(ttl);
        TimeUnit timeUnit = (TimeUnit) annotationAttributes.get("ttlUnit");
        cacheAttribute.setTimeUnit(timeUnit);
        long lockTtl = annotationAttributes.getNumber("lockTtl").longValue();
        cacheAttribute.setLockTtl(lockTtl);
        TimeUnit lockTtlUnit = (TimeUnit) annotationAttributes.get("lockTtlUnit");
        cacheAttribute.setLockTimeUnit(lockTtlUnit);
        return cacheAttribute;
    }

    public DistributedCacheProperties getCacheProperties() {
        return cacheProperties;
    }

    public void setCacheProperties(DistributedCacheProperties cacheProperties) {
        this.cacheProperties = cacheProperties;
    }
}
